今天要完成 Project Section 的區塊,跟昨天的 Hardskills 建立元件的概念差不多。
主要切分成最外層的 project.vue
(父元件),和個別專案卡片區塊 project-card.vue
(子元件)。按鈕部分因為其他地方也可能會用到,所以也可以拉出來做成基底元件,方便區塊使用。
project.vue
要做什麼事?
1. 最外層的切版(Projects 標題、段落敘述、SEE ALL 按鈕)
2. 專案卡片的內容整理,且用 props 傳入子元件
project-card.vue
要做什麼事?
1. 卡片標題
2. 簡述技能(不論多或少都要相同高度 flex-gorw-1
)
3. 按鈕(點按可以前往該網頁,v-if
若無則不顯示按鈕,不一定每個專案都有準備作品簡述)
4. 圖片
5. RWD 配置 (手機版圖片在前 order
)
在畫面設計中,特別針對#簡述技能的區塊進行高度調整,使其能夠撐高以維持與其他元素的一致性,強化整體版面的平衡與專業感。以及手機版畫面時,會優先呈現圖片,再呈現說明文字。
// projects/project-card.vue 子元件
<template>
<div
class="bg-white d-flex flex-row"
:class="isDesktop ? 'pa-10 custom-rounded-lg mt-8': 'pa-5 custom-rounded-md mt-5'"
>
<v-row>
<v-col
cols="12" sm="6" md="6" lg="6" class="d-flex flex-column"
:class="isDesktop ? 'order-sm-1 order-2' : 'order-2'"
>
<div class="d-flex flex-column align-start justify-start flex-grow-1">
<div class="text-brown mb-3"
:class="isDesktop ? 'text-h3-semi-bold': 'text-h4-semi-bold'"
>
{{ props.project.title }}
</div>
<div class="flex-grow-1">
<div
v-for="value in props.project.skills"
class="text-brown"
:class="isDesktop ? 'text-h4-medium': 'text-h6-medium'"
>
# {{ value }}
</div>
</div>
</div>
<div class="d-flex mt-5"
:class="isDesktop || isPad? 'flex-row ga-3': 'flex-column ga-3'"
>
<v-btn
v-if="props.project.designConcept != ''"
append-icon="mdi-arrow-right" rounded="xl" size="large"
variant="outlined" color="bg-orange"
@click="window.open(props.project.designConcept, '_blank')"
>
設計理念
</v-btn>
<v-btn
v-if="props.project.productUrl != ''"
append-icon="mdi-arrow-right" rounded="xl" size="large"
color="bg-orange"
@click="window.open(props.project.productUrl, '_blank')"
>
產品網址
</v-btn>
</div>
</v-col>
<v-col
cols="12" sm="6" md="6" lg="6"
:class="isDesktop ? 'order-sm-2 order-1' : 'order-1'"
>
<img src="https://placehold.co/700x440" alt="project-pic" class="w-100"/>
</v-col>
</v-row>
</div>
</template>
父元件引用子元件:
// projects/projects.vue
<template>
<div class="px-md-12 px-lg-16 px-8 py-16 bg-light-yellow">
<div class="text-brown text-h3-semi-bold mb-3 text-center">
Projects
</div>
<div class="mt-5 text-brown"
:class="isDesktop ? 'text-h5-regular custom-padding': 'text-h6-regular'">
文字說明文字說明文字說明文字說明
</div>
<div v-for="(project, index) in projects" :key="index">
<ProjectCard :project="project"></ProjectCard>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
import ProjectCard from './project-card.vue';
const projects = ref([
{
title: 'title',
skills: ['skill1', 'skill2', 'skill3'],
designConcept: 'url',
productUrl: 'url',
},
...,
]);
</script>
注意 : 建立元件很常會需要搭配 v-for
使用,剛開始真的頭腦轉不過來,建議先用最直覺的方式 —— 直接複製貼上,把所有結構都寫出來,再觀察哪些部分是重複的。接著,再把這些重複區塊抽取成變數或props
,進一步拆分成元件。
https://placehold.co/700x440
https://picsum.photos/id/1011/600/360